#include "asyncnetworkmanager.h"
#include <QDebug>
#include <QJsonDocument>
#include <QUuid>
#include <QtMath>

AsyncNetworkManager::AsyncNetworkManager(QObject *parent)
    : QObject(parent)
    , m_networkThread(nullptr)
    , m_webSocket(nullptr)
    , m_isConnected(false)
    , m_sendTimer(new QTimer())
    , m_heartbeatTimer(new QTimer())
    , m_reconnectTimer(new QTimer())
    , m_statsTimer(new QTimer())
    , m_heartbeatInterval(1000)
    , m_reconnectAttempts(0)
    , m_compressionEnabled(false)
    , m_maxRetries(3)
    , m_sendInterval(5)
    , m_lastHeartbeatTime(0)
    , m_nextMessageId(1)
{
    // 初始化网络统计
    m_stats.latency = 0;
    m_stats.packetLoss = 0;
    m_stats.bandwidth = 0;
    m_stats.messagesPerSecond = 0;
    m_stats.totalBytesSent = 0;
    m_stats.totalBytesReceived = 0;
    
    // 将本组件作为纯客户端侧辅助（不再自管WebSocket线程/定时器），避免跨线程触碰底层socket
    // 由专用NetworkThread + WebSocketClient负责真正的网络I/O

    qDebug() << "AsyncNetworkManager: 异步网络管理器初始化完成 (轻量模式)";
    qDebug() << "  发送间隔:" << m_sendInterval << "ms";
    qDebug() << "  心跳间隔:" << m_heartbeatInterval << "ms";
    qDebug() << "  最大重试次数:" << m_maxRetries;
}

AsyncNetworkManager::~AsyncNetworkManager()
{
    disconnectFromServer();
    
    if (m_webSocket) {
        m_webSocket->deleteLater();
    }
    
    // 清理定时器
    m_sendTimer->deleteLater();
    m_heartbeatTimer->deleteLater();
    m_reconnectTimer->deleteLater();
    m_statsTimer->deleteLater();
    
    qDebug() << "AsyncNetworkManager: 异步网络管理器已销毁";
}

void AsyncNetworkManager::connectToServer(const QString &url)
{
    qDebug() << "AsyncNetworkManager: 连接到服务器:" << url;
    
    m_serverUrl = url;
    m_reconnectAttempts = 0;
    
    if (m_webSocket && !m_isConnected) {
        m_webSocket->open(QUrl(url));
    }
}

void AsyncNetworkManager::disconnectFromServer()
{
    qDebug() << "AsyncNetworkManager: 断开服务器连接";
    
    m_isConnected = false;
    
    // 停止所有定时器
    m_sendTimer->stop();
    m_heartbeatTimer->stop();
    m_reconnectTimer->stop();
    m_statsTimer->stop();
    
    // 关闭WebSocket连接
    if (m_webSocket) {
        m_webSocket->close();
    }
    
    // 清空消息队列
    QMutexLocker locker(&m_queueMutex);
    m_messageQueue.clear();
    m_pendingAcks.clear();
}

void AsyncNetworkManager::sendMessage(const QJsonObject &message, MessagePriority priority, bool requiresAck)
{
    NetworkMessage netMsg;
    netMsg.data = message;
    netMsg.priority = priority;
    netMsg.timestamp = QDateTime::currentMSecsSinceEpoch();
    netMsg.retryCount = 0;
    netMsg.messageId = QUuid::createUuid().toString();
    netMsg.requiresAck = requiresAck;
    
    // 添加消息ID到数据中
    QJsonObject msgWithId = message;
    msgWithId["message_id"] = netMsg.messageId;
    msgWithId["timestamp"] = netMsg.timestamp;
    netMsg.data = msgWithId;
    
    // 加入优先级队列
    QMutexLocker locker(&m_queueMutex);
    
    // 根据优先级插入到合适位置
    bool inserted = false;
    for (auto it = m_messageQueue.begin(); it != m_messageQueue.end(); ++it) {
        if (priority > it->priority) {
            m_messageQueue.insert(it, netMsg);
            inserted = true;
            break;
        }
    }
    
    if (!inserted) {
        m_messageQueue.enqueue(netMsg);
    }
    
    // 如果需要确认，添加到待确认列表
    if (requiresAck) {
        m_pendingAcks[netMsg.messageId] = netMsg.timestamp;
    }
    
    qDebug() << "AsyncNetworkManager: 消息加入队列，优先级:" << priority 
             << "队列大小:" << m_messageQueue.size();
    
    // 启动发送定时器
    if (!m_sendTimer->isActive() && m_isConnected) {
        m_sendTimer->start();
    }
}

void AsyncNetworkManager::sendUserInput(int direction, int sequenceNumber)
{
    QJsonObject inputMsg;
    inputMsg["type"] = "change_direction";
    inputMsg["direction"] = direction;
    inputMsg["sequence_number"] = sequenceNumber;
    inputMsg["room_id"] = ""; // TODO: 从游戏状态获取
    
    // 用户输入使用最高优先级
    sendMessage(inputMsg, PRIORITY_CRITICAL, true);
    
    qDebug() << "AsyncNetworkManager: 发送用户输入，方向:" << direction 
             << "序列号:" << sequenceNumber;
}

void AsyncNetworkManager::setNetworkConfig(bool enableCompression, int maxRetries, int heartbeatInterval)
{
    m_compressionEnabled = enableCompression;
    m_maxRetries = maxRetries;
    m_heartbeatInterval = heartbeatInterval;
    
    m_heartbeatTimer->setInterval(heartbeatInterval);
    
    qDebug() << "AsyncNetworkManager: 网络配置更新";
    qDebug() << "  压缩:" << (enableCompression ? "启用" : "禁用");
    qDebug() << "  最大重试:" << maxRetries;
    qDebug() << "  心跳间隔:" << heartbeatInterval << "ms";
}

void AsyncNetworkManager::onConnected()
{
    qDebug() << "AsyncNetworkManager: WebSocket连接成功";
    
    m_isConnected = true;
    m_reconnectAttempts = 0;
    
    // 轻量模式：不在此组件内启动任何定时器
    
    emit connectionStateChanged(true);
}

void AsyncNetworkManager::onDisconnected()
{
    qDebug() << "AsyncNetworkManager: WebSocket连接断开";
    
    m_isConnected = false;
    
    // 轻量模式：不在此组件内管理定时器/重连
    emit connectionStateChanged(false);
}

void AsyncNetworkManager::onMessageReceived(const QString &message)
{
    qint64 receiveTime = QDateTime::currentMSecsSinceEpoch();
    m_stats.totalBytesReceived += message.toUtf8().size();
    
    // 解析JSON消息
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error);
    
    if (error.error != QJsonParseError::NoError) {
        qDebug() << "AsyncNetworkManager: JSON解析错误:" << error.errorString();
        return;
    }
    
    QJsonObject jsonObj = doc.object();
    handleReceivedMessage(jsonObj);
}

void AsyncNetworkManager::onSocketError(QAbstractSocket::SocketError error)
{
    QString errorString = m_webSocket->errorString();
    qDebug() << "AsyncNetworkManager: WebSocket错误:" << error << errorString;
    
    emit networkError(errorString);
}

void AsyncNetworkManager::onSendTimer()
{
    processMessageQueue();
}

void AsyncNetworkManager::onHeartbeatTimer()
{
    if (!m_isConnected) {
        return;
    }
    
    // 发送心跳消息
    QJsonObject heartbeat;
    heartbeat["type"] = "heartbeat";
    heartbeat["client_timestamp"] = QDateTime::currentMSecsSinceEpoch();
    
    sendMessage(heartbeat, PRIORITY_LOW, false);
    
    m_lastHeartbeatTime = QDateTime::currentMSecsSinceEpoch();
}

void AsyncNetworkManager::onStatsTimer()
{
    updateNetworkStats();
    emit networkStatsUpdated(m_stats);
}

void AsyncNetworkManager::processMessageQueue()
{
    if (!m_isConnected) {
        return;
    }
    
    QMutexLocker locker(&m_queueMutex);
    
    if (m_messageQueue.isEmpty()) {
        m_sendTimer->stop();
        return;
    }
    
    // 发送队列中的下一条消息
    sendNextMessage();
}

void AsyncNetworkManager::sendNextMessage()
{
    if (m_messageQueue.isEmpty()) {
        return;
    }
    
    NetworkMessage message = m_messageQueue.dequeue();
    
    // 转换为JSON字符串
    QJsonDocument doc(message.data);
    QByteArray data = doc.toJson(QJsonDocument::Compact);
    
    // 如果启用压缩
    if (m_compressionEnabled && data.size() > 100) {
        data = compressMessage(data);
    }
    
    // 发送消息
    if (m_webSocket && m_isConnected) {
        m_webSocket->sendTextMessage(QString::fromUtf8(data));
        m_stats.totalBytesSent += data.size();
        
        qDebug() << "AsyncNetworkManager: 发送消息，类型:" << message.data["type"].toString()
                 << "大小:" << data.size() << "字节";
    }
}

void AsyncNetworkManager::handleReceivedMessage(const QJsonObject &jsonObj)
{
    QString messageType = jsonObj["type"].toString();
    qint64 serverTimestamp = jsonObj["timestamp"].toVariant().toLongLong();
    
    if (messageType == "game_state_update") {
        emit gameStateReceived(jsonObj, serverTimestamp);
    } else if (messageType == "input_ack") {
        int sequenceNumber = jsonObj["sequence_number"].toInt();
        emit inputAcknowledged(sequenceNumber, serverTimestamp);
        
        // 从待确认列表中移除
        QString messageId = jsonObj["message_id"].toString();
        m_pendingAcks.remove(messageId);
    } else if (messageType == "heartbeat_ack") {
        // 计算延迟
        qint64 clientTimestamp = jsonObj["client_timestamp"].toVariant().toLongLong();
        int latency = calculateLatency(clientTimestamp);
        m_latencyHistory.append(latency);
        
        // 限制历史大小
        while (m_latencyHistory.size() > 100) {
            m_latencyHistory.removeFirst();
        }
    }
}

void AsyncNetworkManager::updateNetworkStats()
{
    // 计算平均延迟
    if (!m_latencyHistory.isEmpty()) {
        int sum = 0;
        for (int latency : m_latencyHistory) {
            sum += latency;
        }
        m_stats.latency = sum / m_latencyHistory.size();
    }
    
    // 计算丢包率
    int totalPending = m_pendingAcks.size();
    int expiredAcks = 0;
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    
    for (auto it = m_pendingAcks.begin(); it != m_pendingAcks.end();) {
        if (currentTime - it.value() > 5000) { // 5秒超时
            expiredAcks++;
            it = m_pendingAcks.erase(it);
        } else {
            ++it;
        }
    }
    
    if (totalPending > 0) {
        m_stats.packetLoss = (expiredAcks * 100) / totalPending;
    }
    
    // 计算带宽（简化版本）
    static qint64 lastStatsTime = 0;
    static qint64 lastBytesSent = 0;
    static qint64 lastBytesReceived = 0;
    
    if (lastStatsTime > 0) {
        qint64 timeDiff = currentTime - lastStatsTime;
        if (timeDiff > 0) {
            qint64 bytesSent = m_stats.totalBytesSent - lastBytesSent;
            qint64 bytesReceived = m_stats.totalBytesReceived - lastBytesReceived;
            m_stats.bandwidth = ((bytesSent + bytesReceived) * 1000) / timeDiff;
        }
    }
    
    lastStatsTime = currentTime;
    lastBytesSent = m_stats.totalBytesSent;
    lastBytesReceived = m_stats.totalBytesReceived;
}

int AsyncNetworkManager::calculateLatency(qint64 clientTimestamp)
{
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    return qMax(0, int(currentTime - clientTimestamp));
}

QByteArray AsyncNetworkManager::compressMessage(const QByteArray &data)
{
    // 简化的压缩实现（实际应该使用zlib或其他压缩库）
    return qCompress(data);
}

QByteArray AsyncNetworkManager::decompressMessage(const QByteArray &data)
{
    // 简化的解压实现
    return qUncompress(data);
}
